package com.davidhigenbottam.HeatMap.client;

import java.util.HashMap;

import com.davidhigenbottam.HeatMap.shared.Query;
import com.davidhigenbottam.HeatMap.shared.Results;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class OverlaysCache {
	static final int MAX_NUMBER_OF_RETRIES=3;
	
	HashMap<String, OverlayData> overlayCache = new HashMap<String, OverlayData>();
	HashMap<String, InstitutionOverlayData> institutionOverlayCache = new HashMap<String, InstitutionOverlayData>();
	int numberOfRetries= 0;
	UI ui= UI.getInstance();
	
	private boolean detectClickWithNoChangeFlag=false;
	
	public OverlaysCache() {
		ui.getOverLayListBox().setVisibleItemCount(6);
		ui.getOverLayListBox().addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				int selectedIndex = ui.getOverLayListBox().getSelectedIndex();
				OverlayData selectedOverlay= fetchOverlayFromCache(ui.getOverLayListBox().getValue(selectedIndex));
				hideVisibleOverlay();
				selectedOverlay.show();
				HeatMap.info("onChange :"+detectClickWithNoChangeFlag);
				detectClickWithNoChangeFlag=true;
			}
		});
		
		ui.getOverLayListBox().addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				//handle the case when click on a selected item to deselect i.e. remove all overlays
				//event.
				HeatMap.info("onClick :"+detectClickWithNoChangeFlag);
				if(detectClickWithNoChangeFlag){
					//we have had a change so do nothing
				}
				else{
					//unslect and remove overlay
					//int selectedIndex = ui.getOverLayListBox().getSelectedIndex();
					ui.getOverLayListBox().setSelectedIndex(-1);
					//ui.getOverLayListBox().setItemSelected(selectedIndex, false);
					hideVisibleOverlay();
				}
					
				detectClickWithNoChangeFlag= false;
				
			}});
		
		
	}
	
	public void hideVisibleInstitutionOverlay() {
		for (InstitutionOverlayData o : institutionOverlayCache.values()) {
			if (!o.isHidden())
				o.hide();
		}
		
	}	
	public void hideVisibleOverlay() {
		hideVisibleInstitutionOverlay();
		for (OverlayData o : overlayCache.values()) {
			//if (!o.isHidden())
			o.hide();
		}
		
	}
	
	public OverlayData fetchOverlayFromCache(String kmlUrl) {
		return overlayCache.get(kmlUrl);
	}
	public InstitutionOverlayData fetchInstitutionOverlayFromCache(String kmlUrl) {
		return institutionOverlayCache.get(kmlUrl);
	}	
	
	private void showExistingOverlayData(OverlayData od){
//		ui.getMap().setCenter(od.getCenter());
		od.show();
		ui.stopWaiting();
	}
	
//	private void showExistingInstitutionOverlayData(InstitutionOverlayData iod){
//		//ui.getMap().setCenter(iod.getCenter());
//		iod.show();
//		ui.hideWaiting();
//	}	
	

	
	public void runQuery(Query q) {
		hideVisibleOverlay();

		String url= q.getKmlUrl();
		
		// first check if we already have this overlay in the cache
		OverlayData od = fetchOverlayFromCache(url);
		
		if (od != null) {
			HeatMap.logger.info("found overlay in cache");
			showExistingOverlayData(od);
		} 
		else {
			//create empty OverlayData and put it in the cache 
			//as we don't know which service will return first
			OverlayData emptyOd= new OverlayData(q);
			overlayCache.put(url, emptyOd);
			
			numberOfRetries=0;

			requestKmlOverlay(q, emptyOd);
			requestQueryData(q);

		}
	}
	
	
	
	
	public void requestKmlOverlay(final Query q, OverlayData od) {

		String kmlUrl = q.getKmlUrl();
		
		// request kml to create overlay

		HeatMap.info("About to get kml via url:" + kmlUrl);
		
		
		od.setOverlay(UI.getInstance().getMap().createKmlLayer(kmlUrl));
		ui.getOverLayListBox().addItem(q.getDescription(), kmlUrl);
		ui.getOverLayListBox().setItemSelected(ui.getOverLayListBox().getItemCount()-1, true);
		ui.showOverlays();
		

		ui.addUrls(kmlUrl,q.getExcelUrl(),q.getDescription());
		
		ui.updateMapTitle(q);
		
				
	
	}	
	
	
	
	
	
	
	
	public void requestQueryData(final Query q) {

		// Set up the callback object.
		AsyncCallback<Results> callback = new AsyncCallback<Results>() {
			public void onFailure(Throwable caught) {
				HeatMap.error("getProvinceData:onFailure", caught);
				ui.stopWaiting();	
			}

			public void onSuccess(Results results) {
				if (results != null) {
					
//					for(Province p: provs){
//						HeatMap.logger.log(Level.INFO,"ProvinceTable p val:"+p.getVal());
//					}
					
					//find OverlayData in cache
					OverlayData od = fetchOverlayFromCache(q.getKmlUrl());
					if(od==null){
						HeatMap.error("heatmapService.provinces:onSuccess() url:"+q.getKmlUrl()+" not found in cache");
						return;
					}
					od.addResults(results);
					
					
					if(results.hasInstitutions()){
						od.setInstitutionsLayer(UI.getInstance().getMap().createInstitutionsLayer(results));
						od.show();
						ui.showInstitutionKey();
					}	
					ui.stopWaiting();	
				}
			}
		};

		// Make the call to the service.
		HeatMap.heatmapService.getResults(q, callback);
	}
	
//	public void runInstitutionQuery(Query query) {
//		
//		hideVisibleInstitutionOverlay();
//		ui.showWaitingDialog();
//		String url= query.getKmlUrl();
//		
//		// first check if we already have this overlay in the cache
//		InstitutionOverlayData iod = fetchInstitutionOverlayFromCache(url);
//		
//		if (iod != null) {
//			HeatMap.logger.info("found institution overlay in cache");
//			showExistingInstitutionOverlayData(iod);
//		} 
//		else {
//			//create empty OverlayData and put it in the cache 
//			//as we don't know which service will return first
//			InstitutionOverlayData emptyIod= new InstitutionOverlayData(query);
//			institutionOverlayCache.put(url, emptyIod);
//			
//			numberOfRetries=0;
//			//now call the two asynchronous calls one for the KML overlay the
//			//other for the raw province data
//			
//			//requestOverlay(q);
//			requestInstitutionData(query);
//			
//		}	
//	}
//	public void requestInstitutionData(final Query q) {
//
//		// Set up the callback object.
//		AsyncCallback<Results> callback = new AsyncCallback<Results>() {
//			public void onFailure(Throwable caught) {
//				HeatMap.error("requestInstitutionData", caught);
//				ui.hideWaiting();
//			}
//
//			public void onSuccess(Results res) {
//				if (institutions != null) {
//
//					//find OverlayData in cache
//					InstitutionOverlayData iod = fetchInstitutionOverlayFromCache(q.getKmlUrl());
//					if(iod==null){
//						HeatMap.error("heatmapService.institutions:onSuccess() url:"+q.getKmlUrl()+" not found in cache");
//						return;
//					}					
//					InstitutionTable it= iod.getInstitutionTable();
//					ListDataProvider<Institution> dp= it.getDataProvider();
//					dp.setList(institutions);
//					
//					ui.addResultsTable(it);
//					it.show();
//					it.addSortHandlers();
//
//				}
//				ui.hideWaiting();
//			}
//		};
//
//		// Make the call to the service.
//		HeatMap.heatmapService.getResults(q, callback);
//	}	
//
//
//	
//	

		
	
	
	
	
	
}
